package chatModel;

import java.util.HashMap;
import java.util.Observable;
import javax.swing.DefaultListModel;

/* 
 * @author deepali and vansh
 */
public class ChatModel extends Observable {

    /**
     * @param localUser this parameter local user is a "user" and it defines the
     * local user who is the client on this machine
     * @param localUserIsConnected this parameter is a boolean and it indicates
     * if the user local user is connected or not
     * @param ConnectedUsers this parameter represents the list of the connected
     * users
     * @param converstations this parameter list represents the list of the
     * current converstaions
     * @param hashmapConv this parameter is a HashMap between each the user and
     * each conversation
     * @param hashmapUsers this parameter is a HashMap between the user and the
     * user name
     * @param presentstill it tells if a user is present in the user-list or not
     */
    private User localUser;
    private boolean localUserIsConnected;
    private DefaultListModel connectedUsers;
    private DefaultListModel conversations;
    private HashMap<User, Conversation> hashmapConv;
    private HashMap<String, User> hashmapUsers;
    private boolean presentstill;

    public boolean isPresentstill() {
        return presentstill;
    }

    public void setPresentstill(boolean presentstill) {
        this.presentstill = presentstill;
    }

    public enum Val {

        CONNEXIONSTATE
    }

    /**
     * The chat Model is a part of the model view controller design pattern that
     * allows use to organize the chat system
     */
    public ChatModel() {
        this.connectedUsers = new DefaultListModel();
        this.hashmapUsers = new HashMap<String, User>();
        this.localUserIsConnected = false;
        this.conversations = new DefaultListModel();
        this.hashmapConv = new HashMap<User, Conversation>();
        this.presentstill = true;
    }

    /**
     * This method allows us to set the state of the local user if he is
     * connected or not
     */
    public void setLocalUserIsConnected(boolean b) {
        this.localUserIsConnected = b;
        this.setChanged();
        notifyObservers(Val.CONNEXIONSTATE);
    }

    /**
     * this method allows us to set the local user
     */
    public void setLocalUser(User localUser) {
        this.localUser = localUser;
    }

    /**
     * this method allows us to get the local user
     */
    public User getLocalUser() {
        return localUser;
    }

    /**
     * this method allows us to get the state of the local user
     */
    public boolean getLocalUserIsConnected() {
        return localUserIsConnected;
    }

    /**
     * this method allows us to get the list of the connected users
     */
    public DefaultListModel getConnectedUsers() {
        return connectedUsers;
    }

    /**
     * this method allows us to get the list of the converstaions
     */
    public DefaultListModel getConversations() {
        return conversations;
    }

    /**
     * this method allows us to get the HashMap between the user and the
     * conversation
     */
    public HashMap<User, Conversation> getHashmapConv() {
        return hashmapConv;
    }

    /**
     * this method allows us to get the HashMap between the user and the user
     * name
     */
    public HashMap<String, User> getHashmapUsers() {
        return hashmapUsers;
    }

    /**
     * this method allows us to add the user in the list of the connected users
     */
    public void addUserInList(User newUser) {
        if (!hashmapUsers.containsKey(newUser.getUsername())) {
            presentstill = false;
            connectedUsers.addElement(newUser);
            hashmapUsers.put(newUser.getUsername(), newUser);
            this.setChanged();
            notifyObservers(newUser.getUsername());
        } else {
            presentstill = true;
        }
    }

    /**
     * this method allows us to remove the user from the list of the connected
     * users and in the HashMap
     */
    public void removeUserFromList(User exitingUser) {
        connectedUsers.removeElement(exitingUser);
        hashmapUsers.remove(exitingUser.getUsername());
    }

    /**
     * this method allows us to add a conversation in the list of the
     * conversations and in the HashMap 
     *
     */
    public void addConversations(Conversation c) {
        if (!conversations.contains(c)) {
            conversations.addElement(c);
            hashmapConv.put(c.getRemoteUser(), c);
            System.out.println("adding " + c);
        }
    }

    /**
     * this method allows us to create a new conversation with remote user 
     *
     */
    public Conversation createConversation(User remoteUser) {
        Conversation c = new Conversation(remoteUser);
        conversations.addElement(c);
        hashmapConv.put(remoteUser, c);
        return c;
    }

    /**
     * this method allows us to remove a conversation  
     *
     */
    public void removeConversation(Conversation c) {
        conversations.removeElement(c);
        hashmapConv.remove(c.getRemoteUser());
    }
}
